package com.huijie.app.common;

import com.huijie.app.u.entity.User;
import com.huijie.app.u.service.ITokenService;
import com.huijie.app.u.service.IUserService;
import com.huijie.app.sys.aspect.ControllerParamRecord;
import com.huijie.app.util.TokenUtil;
import com.huijie.app.u.bean.TokenVO;
import com.huijie.app.u.bean.UserLoginVO;
import com.huijie.core.bean.ResponseBean;
import com.huijie.core.bean.ResponseCodeMsgBean;
import com.huijie.core.constant.ResponseCode;
import com.huijie.core.common.BaseController;
import com.huijie.core.util.ResponseMsgUtil;
import io.jsonwebtoken.SignatureAlgorithm;
import io.swagger.annotations.*;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.util.AntPathMatcher;
import org.apache.shiro.util.PatternMatcher;
import org.jsets.shiro.util.ShiroUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.UUID;

/**
 * @ClassName CommonController
 * @Description RFID 全局API控制器
 * @Author Alex
 * @Date 2018/7/13 09:39
 * @Version 1.0
 */
@RestController
@Api(tags = {"1、全局相关API-登陆"}, description = "\"1-1,1-2\"", position = 1)
public class CommonController extends BaseController {

    private final IUserService userService;
    private final ITokenService tokenService;

    @Autowired
    public CommonController(IUserService userService, ITokenService tokenService) {
        this.userService = userService;
        this.tokenService = tokenService;
    }

    private final static String SECRET_KEY = "ofaffadfev1234567--090swctewst";

    @ApiOperation(value = "(1-1)登陆认证-后台管理前端用户", notes = "登陆成功签发令牌返回")
    @ApiImplicitParam(name = "accountVo", value = "用户实体", required = true, dataType = "UserLoginVO", paramType = "body")
    @ApiResponses(value = {
            @ApiResponse(code = 800, message = "通用：传参不合法"),
            @ApiResponse(code = 900, message = "通用：API错误"),
            @ApiResponse(code = 501, message = "业务：username_required 用户名不能为空"),
            @ApiResponse(code = 502, message = "业务：password_required 密码不能为空"),
            @ApiResponse(code = 507, message = "业务：invalid_usertype 无效的用户类型"),
            @ApiResponse(code = 503, message = "业务：username_or_password_mismatch 用户名或密码不匹配")
    })
    @PostMapping(value = "/login-check", produces = "application/json; charset=utf-8")
    @ControllerParamRecord(description = "登陆认证")
    public ResponseEntity<ResponseBean> loginCheckStaff(@Valid @RequestBody UserLoginVO accountVo, HttpServletRequest request, BindingResult bindingResult) {
        String username = accountVo.getUsername();
        String password = accountVo.getPassword();
        //1.用户名不能为空
        if (StringUtils.isEmpty(username)) {
            log.error("登陆认证失败,原因:用户名不能为空");
            return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.USERNAME_REQUIRED, null));
        }
        //2.密码不能为空
        if (StringUtils.isEmpty(password)) {
            log.error("登陆认证失败,原因:密码不能为空");
            return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_LOGIN_PASS_NULL, null));
        }
        int userType = accountVo.getUserType();
        User user = userService.getUserByloginName(username);
        Integer userId = 0;
        String deptCode = null;
        String deptName = null;
        String staffName = null;
        if (user != null && user.getPassword().equals(password)) {
            userId = user.getId();
            staffName = user.getUserName();
        }

        if (userId != 0) {
            String token = this.applyToken(request, username, userId, userType);
            TokenVO staffVo = new TokenVO();
            staffVo.setToken(token);
            staffVo.setExpiresIn(String.valueOf(TokenUtil.JWT_PERIOD / 1000));
            staffVo.setUserType(userType);
            staffVo.setCode(deptCode);
            staffVo.setName(deptName);
            staffVo.setEmpName(staffName);
            return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_SUCCESS, staffVo));
        }
        return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_LOGIN_UNKNOWN_FAIL, null));
    }

    /**
     * @return com.cn.rfid.model.vo.base.ResponseCodeMsgBean
     * @description: 需要认证 信息返回
     * @author Alex
     * @date 2018/11/29 10:37
     */
    @ApiIgnore
    @RequestMapping("/need-login")
    public ResponseCodeMsgBean returnNeedAuthMsg() {
        return ResponseMsgUtil.returnCodeMessage(ResponseCode.JWT_TOKEN_IS_MISSING);
    }

    /**
     * @return com.cn.rfid.model.vo.base.ResponseCodeMsgBean
     * @description: 需要认证 信息返回
     * @author Alex
     * @date 2018/11/29 10:38
     */
    @ApiIgnore
    @GetMapping("/unauthorized")
    public ResponseCodeMsgBean returnUnauthorizedMsg() {
        return ResponseMsgUtil.returnCodeMessage(ResponseCode.INVALID_CREDENCIAL1);
    }

    /**
     * @param request
     * @param clientKey 客户端钥匙
     * @param id        用户ID
     * @param userType  用户类型
     * @return java.lang.String
     * @description: 签发一个Json Web Token
     * @author Alex
     * @date 2018/11/29 10:39
     */
    private String applyToken(HttpServletRequest request, String clientKey, Integer id, int userType) {
        // 令牌ID=uuid，用户=clientKey
        // token有效期毫秒，用户角色=null,用户权限=create,read,update,delete
        // permissions: create,read,update,delete
        return tokenService.issueJwt(request, UUID.randomUUID().toString(), clientKey,
                "token-server", TokenUtil.JWT_PERIOD, null, "",
                SignatureAlgorithm.HS512, id, userType);
    }

    @ApiOperation(value = "(1-3)权限刷新", notes = "权限刷新")
    @RequestMapping(value = "/reloadRules", method = RequestMethod.GET, produces = "application/json; charset=utf-8")
    public ResponseEntity<ResponseBean> reloadRules() {
        ShiroUtils.reloadFilterRules();
        return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_SUCCESS, null));
    }

    @ApiOperation(value = "(1-4)urlTest", notes = "urlTest")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pathPattern", value = "url规则", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "url", value = "url", required = true, dataType = "String", paramType = "query"),
    })
    @RequestMapping(value = "/urlTest", method = RequestMethod.POST, produces = "application/json; charset=utf-8")
    public ResponseEntity<ResponseBean> urlTest(String pathPattern, String url) {
        PatternMatcher antPathMatcher = new AntPathMatcher();
        if (antPathMatcher.matches(pathPattern, url)) {
            return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_SUCCESS, true));
        }
        return ResponseEntity.ok(ResponseMsgUtil.returnCodeMessage(ResponseCode.GLOBAL_SUCCESS, false));
    }
}